#include <iostream>
#include <sstream>
#include <string>
#include <map>

#include "Player.h"
#include "PokerTool.h"


using namespace std;

void Player::setFitness(int _fitness)
{
	this->fitness = _fitness;
}
int Player::getBetInt()
{
 if(bet < 0)
  return 0;
 return bet;
}

int Player::getBankrollInt()
{
 return bankroll;
}

void Player::setBankroll(int _bankroll)
{
 bankroll = _bankroll;
}

void Player::setBet(int _bet)
{
 bet = _bet;
}

int Player::getMise()
{
 if(mise < 0)
  return 0;
 return mise;
}

void Player::setMise(int _mise)
{
 mise = _mise;
}

void Player::setAmountToCall(int _amountToCall)
{
 if(_amountToCall < 0)
  amountToCall = 0;
 else
  amountToCall = _amountToCall;
}

int Player::getAmountToCall()
{
 if(amountToCall <0)
  return 0;
 return amountToCall;
}

void Player::setAmountRaised(int _amountRaised)
{
 amountRaised = _amountRaised;
}

int Player::getAction(string act)
{
	for(int i = 0; i < 3 ; i++)
	{
		if(choice[i]==act)
			return i;
	}
	return 0;
}

void Player::setAction(int i)
{
 setAction(choice[i].c_str());
}

int Player::getFitness()
{
 return fitness;
}

QString Player::getCombinationLabel()
{
 return combinationLabel;
}

string Player::getBlind(int bigblind)
{
 if((bigblind/position) < 0)
  return "0";

 // retourne la bigblind / par la position
 return PokerTool::intToString((bigblind/position));
}

//string Player::decisionDataBase()
//{
//	// int to string : miseMinimun
//	string st = PokerTool::intToString( (amountRaised*bigblind) );
//
//	string ret="";
//
//	//fold
//	if(action=="0")
//	{
//		ret =  "["+name.toStdString()+"["+choice[0]+"][0]]";
//	}
//	//call
//	else if(action=="1")
//	{
//		ret =  "["+name.toStdString()+"["+choice[1]+"]["+st+"]]";
//	}
//	//raise
//	else if(action=="2")
//	{
//		ret = "["+name.toStdString()+"["+choice[2]+"]["+st+"]]";
//	}
//	else
//	{
//		ret =  "["+name.toStdString()+"["+choice[0]+"][0]]";
//	}
//
//	return ret;getBigBlind
//}

string Player::randomDecisionRaiseOrCheck()
{
	string response;

	// int to string : miseMinimun
	string st = PokerTool::intToString(amountToCall);

	srand(time(NULL));
	int c = rand()%100;

	//suit :
	if( c < 66 )
	{
		response = "["+name.toStdString()+"["+choice[1]+"]["+st+"]]";
	}

	//misé plus : raise
	else if( c >= 66 )
	{
		int mi = amountToCall + (rand()%(bankroll-amountToCall))/10;
		if(mi > bankroll ) mi = bankroll;
		if(mi < 0) mi = 0;

		// int to string : miseMinimun / amountToCall
    	string st2 = PokerTool::intToString(mi);

		response = "["+name.toStdString()+"["+choice[2]+"]["+st2+"]]";
	}
	return response;
}

string Player::randomDecision(Player & player)
{
	string response;

	srand(time(NULL));
	int c = rand()%100;

	//couche : fold
	if( c <= 9 )
	{
		player.setAction(0);
		player.setMise(0);
		response = "["+name.toStdString()+"["+choice[0]+"][0]]";
	}

	//suit : 
	if( c > 9 && c < 66 )
	{
		player.setAction(1);
		player.setMise(amountToCall);
		response = "["+name.toStdString()+"["+choice[1]+"]["+PokerTool::intToString(amountToCall)+"]]";
	}

	//misé plus : raise
	else if( c >= 66 )
	{
		int mi = amountToCall + (rand()%(bankroll-amountToCall))/10;
		if(mi > bankroll ) mi = bankroll;
		if(mi < 0) mi = 0;

		player.setAction(2);
		player.setMise(mi);
		response = "["+name.toStdString()+"["+choice[2]+"]["+PokerTool::intToString(mi)+"]]";
	}
	return response;
}
string Player::toString(int betOther,int etat, int fitness,int winner)
{
	string ret;
	ret.append("[partie");
		ret.append("[joueur");
		//TODO: etat de la partioe encours dans gameInfo
			//ret.append("[etat["+st3+"]]");
			ret.append("[etat["+PokerTool::intToString(etat)+"]]");
			ret.append("[fitness["+PokerTool::intToString(fitness)+"]]");
			ret.append("[winner["+PokerTool::intToString(winner)+"]]");
			ret.append("[betOther["+PokerTool::intToString(betOther)+"]]");

			ret.append("[strategy["+strategy.toStdString()+"]]");
			ret.append("[argent["+PokerTool::intToString(bankroll)+"]]");
			ret.append("[argentMin["+PokerTool::intToString(amountToCall)+"]]");
			ret.append("[position["+PokerTool::intToString(position)+"]]");
			ret.append("[bigblind["+PokerTool::intToString(BIGBLIND)+"]]");

			ret.append("["+hand[0].toString().toStdString()+"]" );
			ret.append("["+hand[1].toString().toStdString()+"]" );
		ret.append("]");
	ret.append("]");

	return ret;
}

void Player::printHandle()
{
 cout << "carte du joueur : " << name.toStdString() << endl;
 cout << "       carte 1 : " << hand[0].toString().toStdString() << endl << "       carte 2 :" << hand[1].toString().toStdString() << endl;
}

/**
 * Constructor and operator
 */
Player::Player(QString _name)
{
 name = _name;
 bankroll = 100;
 mise = 0;
 amountToCall = 0;
 bet = 0;
 position = 0;
 action = "";
 amountRaised = 0;
 fitness=0;
}

Player::Player()
{
 bankroll = 0;
 mise = 0;
 amountToCall = 0;
 name = "";
 bet = 0;
 position = 0;
 action = "";
 amountRaised = 0;
 fitness=0;
}

Player::Player(const Player & player)
{
 hand[0] = player.hand[0];
 hand[1] = player.hand[1];

 bet = player.bet;
 amountToCall = player.amountToCall;

 bankroll= player.bankroll;
 mise = player.mise;
 action = player.action;
 name = player.name;
 ip = player.ip;
 port = player.port;
 position = player.position;
 strategy = player.strategy;
 amountRaised = player.amountRaised;
 fitness = player.fitness;
}

Player & Player::operator = (const Player & player)
{		
 hand[0] = player.hand[0];
 hand[1] = player.hand[1];

 bet = player.bet;
 amountToCall = player.amountToCall;

 bankroll= player.bankroll;
 mise = player.mise;
 action = player.action;
 name = player.name;
 ip = player.ip;
 port = player.port;
 position = player.position;
 strategy = player.strategy;
 amountRaised = player.amountRaised;
 fitness = player.fitness;

 return *this;
}

/**
 * Getter
 */
Card Player::getCard(int numCard)
{
 return hand[numCard];
}

QString Player::getIp()
{
 return ip;
}

QString Player::getPort()
{
 return port;
}

QString Player::getName()
{
 return name;
}

QString Player::getAction()
{
 return action;
}

int Player::getPosition()
{
 return position;
}

/**
 * Setter
 */
void Player::setCards(QChar cardName1, QChar cardColor1, QChar cardName2, QChar cardColor2)
{
 hand[0].setCardName(cardName1);
 hand[0].setCardColor(cardColor1);
 hand[1].setCardName(cardName2);
 hand[1].setCardColor(cardColor2);
}

void Player::setIp(QString _ip)
{
 ip = _ip;
}

void Player::setPort(QString _port)
{
 port = _port;
}

void Player::setName(QString _name)
{
 name = _name;
}

QString Player::getStrategy()
{
 return strategy;
}

void Player::setPosition(int _position)
{
 position = _position;
}

int Player::getAmountRaised()
{
 if(amountRaised < 0)
  return 0;
 return amountRaised;
}

void Player::setStrategy(QString _strategy)
{
 strategy = _strategy;
}

void Player::setCombinationLabel(QString _combinationLabel)
{
	combinationLabel = _combinationLabel;
}

void Player::setAction(QString _Vaction)
{
	string Vaction = _Vaction.toStdString();
	int pos1= Vaction.find('[',1);
	int pos2= Vaction.find(']',pos1+1);

	if(pos1 !=-1 && pos2 != -1)
	{
		//Récupère l'action du joueur
		action = Vaction.substr(pos1+1,pos2-pos1-1).c_str();

		int pos3= Vaction.find('[',pos2+1);
		int pos4= Vaction.find(']',pos3+1);

		//Récupère la mise du joueur
		mise = PokerTool::stringToInt(Vaction.substr(pos3+1,pos4-pos3-1));
	}
	else
		action = _Vaction;
}

string Player::getBet()
{
	if(bet < 0)
		return "0";
	return PokerTool::intToString(bet);
}

string Player::getBankroll()
{
	if( bankroll < 0)
		return "0";
	return PokerTool::intToString(this->bankroll);
}

string Player::getSommeMiseString()
{
	if(mise < 0)
		return "0";
	return PokerTool::intToString(this->mise);
}

QDomElement Player::toXml(QDomDocument doc)
{
 QDomElement playerElement = doc.createElement("player");
 playerElement.setAttribute("position", QString::number(position));

 if(amountRaised != 0)
 {
  QDomElement amountRaisedElement = doc.createElement("amountRaised");
  QDomText amountRaisedText = doc.createTextNode(QString::number(amountRaised));
  amountRaisedElement.appendChild(amountRaisedText);
  playerElement.appendChild(amountRaisedElement);
 }

 if(strategy != "")
 {
  QDomElement strategyElement = doc.createElement("strategy");
  QDomText strategyText = doc.createTextNode(strategy);
  strategyElement.appendChild(strategyText);
  playerElement.appendChild(strategyElement);
 }

 if(action != 0)
 {
  QDomElement actionElement = doc.createElement("action");
  QDomText actionText = doc.createTextNode(action);
  actionElement.appendChild(actionText);
  playerElement.appendChild(actionElement);
 }

 QDomElement cardElement;

 for(int i=0; i<2; i++)
 {
  cardElement = getCard(i).toXml(doc);
  playerElement.appendChild(cardElement);
 }

 return playerElement;
}
